Adquisición de un monitor de PC mediante métodos multicriterio

Autor/a

Víctor Silva Nieves

1 Presentación del problema

El objetivo de este documento será elegir la mejor alternativa a la hora de adquirir un nuevo monitor de PC. Se van a considerar dos profesionales diferentes como interesados en esta adquisición, para observar como cambian las decisiones en función de las necesidades de cada uno.

Se van a seleccionar 5 monitores diferentes, que tratan de representar una variedad de opciones en el mercado actual. Los criterios que se van a considerar son los siguientes:

  • Precio (€)
  • Tamaño (pulgadas)
  • Frecuencia de actualización (Hz) o de refresco.
  • Resolución (px)
  • Consumo energético (W) en un instante.
  • Densidad de píxeles (ppi)
  • Brillo (nits)
  • Contraste (en millones de colores M)

Y las alternativas las podemos ver en la siguiente tabla:

# Carga de librerías necesarias
library(DiagrammeR)
library(ahp)

# Carga de funciones multicriterio
source("teoriadecision_funciones_multicriterio.R")
source("teoriadecision_funciones_multicriterio_diagram.R")
source("teoriadecision_funciones_multicriterio_utiles.R")

# Carga otras funciones
source("otras_funciones.R")
source("tablas_planteamiento_AHP.R")
datos <- read.csv2("monitores.csv", header = FALSE, sep = ";")
colnames(datos) <- c("Modelo","Precio", "Tamaño", "Frecuencia", "Resolución", "Consumo", "Densidad", "Brillo", "Colores")
unidades <- c("€", "pulgadas", "Hz", "px", "W", "ppi", "nits", "M")

crea_tabla_estilo(datos, nombresfila = FALSE)
Modelo Precio Tamaño Frecuencia Resolución Consumo Densidad Brillo Colores
LG UltraFine 40WT95UF 505 39.7 120 2160 40 139 450 1060
Asus TUF Gaming VG27AQ3A 244 27 180 1440 35 108 250 16.7
MSI MAG401QR 449 40 155 1440 39 93 400 1070
Asus VZ27EHF 108 27 100 1080 21 81 250 16.7
Samsung UJ59 290 31.5 60 2160 37 139 270 1000

El primer interesado en tomar la decisión es un arquitecto que busca un monitor que le permita trabajar con planos y renderizados de alta calidad. El precio le preocupa en poca medida, pero quiere un monitor que ofrezca buena resolución y una buena representación de colores. Además, valora un tamaño grande para facilitar su trabajo.

El segundo interesado es un desarrollador que trabaja con R y Python. Considera el precio es un factor importante. Valora un gran tamaño de pantalla para poder tener varias ventanas abiertas y una buena frecuencia de actualización para evitar la fatiga visual. La resolución o los colores son menos importantes para él.

En cuanto al consumo ambos quieren que sea lo más bajo posible pero ninguno lo valora especialmente.

1.1 Planteamiento para el método AHP

1.1.1 Introducción

Para el método AHP, se va a dar una estructura jerárquica de criterios y subcriterios. Se van a considerar tres criterios: Coste, calidad de imagen y experiencia de usuario.

  • El criterio coste, incluye los subcriterios: precio y consumo energético.

  • El criterio calidad de imagen, incluye los subcriterios: resolución, densidad, brillo y colores.

  • El criterio experiencia de usuario, incluye los subcriterios: tamaño y frecuencia de actualización.

Vemos a continuación un diagrama que representa esta jerarquía:

DiagrammeR::grViz("
digraph {
    node [shape = rectangle, style = 'rounded,filled', fontname = 'Source Sans Pro', fontsize = '12']
    A [label = 'Elección de un monitor', fillcolor = '#C7645D']
    B [label = 'Coste', fillcolor = '#E2807A']
    C [label = 'Calidad de Imagen', fillcolor = '#E2807A']
    D [label = 'Experiencia de Usuario', fillcolor = '#E2807A']
    E [label = 'Precio', fillcolor = '#F8A29E']
    F [label = 'Consumo', fillcolor = '#F8A29E']
    G [label = 'Resolución', fillcolor = '#F8A29E']
    H [label = 'Densidad', fillcolor = '#F8A29E']
    I [label = 'Brillo', fillcolor = '#F8A29E']
    J [label = 'Colores', fillcolor = '#F8A29E']
    K [label = 'Tamaño', fillcolor = '#F8A29E']
    L [label = 'Frecuencia', fillcolor = '#F8A29E']
    edge[color = '#005A89', arrowsize = '0.5']
    A -> {B C D}
    B -> {E F}
    C -> {G H I J}
    D -> {K L}
}")

1.1.2 Matrices de comparación por parejas

A continuación se establecen las siguientes matrices de comparación por parejas para los criterios, subcriterios y alternativas. Se ha realizado en un script anexo llamado “tablas_planteamiento_AHP.R” para una mejor legibilidad.

1.1.2.1 Nivel 1 - Criterios

Coste Calidad de Imagen Experiencia de Usuario
Coste 1 1/7 1/5
Calidad de Imagen 7 1 3
Experiencia de Usuario 5 1/3 1

1.1.2.2 Nivel 2 - Subcriterios:

1.1.2.2.1 Coste:
Precio Consumo
Precio 1 5
Consumo 1/5 1
1.1.2.2.2 Calidad de Imagen:
Resolución Densidad Brillo Colores
Resolución 1 2 7 5
Densidad 1/2 1 5 3
Brillo 1/7 1/5 1 1/3
Colores 1/5 1/3 3 1
1.1.2.2.3 Experiencia de Usuario:
Tamaño Frecuencia
Tamaño 1 3
Frecuencia 1/3 1

1.1.2.3 Nivel 3 - Alternativas:

1.1.2.3.1 Precio:
LG UltraFine 40WT95UF Asus TUF Gaming VG27AQ3A MSI MAG401QR Asus VZ27EHF Samsung UJ59
LG UltraFine 40WT95UF 1 1/7 1/2 1/9 1/5
Asus TUF Gaming VG27AQ3A 7 1 5 1/4 3
MSI MAG401QR 2 1/5 1 1/7 1/4
Asus VZ27EHF 9 4 7 1 5
Samsung UJ59 5 1/3 4 1/5 1
1.1.2.3.2 Consumo:
LG UltraFine 40WT95UF Asus TUF Gaming VG27AQ3A MSI MAG401QR Asus VZ27EHF Samsung UJ59
LG UltraFine 40WT95UF 1 1/4 1/2 1/9 1/3
Asus TUF Gaming VG27AQ3A 4 1 3 1/6 2
MSI MAG401QR 2 1/3 1 1/8 3
Asus VZ27EHF 9 6 8 1 7
Samsung UJ59 3 1/2 1/3 1/7 1
1.1.2.3.3 Resolución:
LG UltraFine 40WT95UF Asus TUF Gaming VG27AQ3A MSI MAG401QR Asus VZ27EHF Samsung UJ59
LG UltraFine 40WT95UF 1 5 5 9 1
Asus TUF Gaming VG27AQ3A 1/5 1 1 3 1/5
MSI MAG401QR 1/5 1 1 3 1/5
Asus VZ27EHF 1/9 1/3 1/3 1 1/9
Samsung UJ59 1 5 5 9 1
1.1.2.3.4 Densidad:
LG UltraFine 40WT95UF Asus TUF Gaming VG27AQ3A MSI MAG401QR Asus VZ27EHF Samsung UJ59
LG UltraFine 40WT95UF 1 3 5 7 1
Asus TUF Gaming VG27AQ3A 1/3 1 3 5 1/3
MSI MAG401QR 1/5 1/3 1 3 1/5
Asus VZ27EHF 1/7 1/5 1/3 1 1/7
Samsung UJ59 1 3 5 7 1
1.1.2.3.5 Brillo:
LG UltraFine 40WT95UF Asus TUF Gaming VG27AQ3A MSI MAG401QR Asus VZ27EHF Samsung UJ59
LG UltraFine 40WT95UF 1 7 2 7 6
Asus TUF Gaming VG27AQ3A 1/7 1 1/3 1 2
MSI MAG401QR 1/2 6 1 6 5
Asus VZ27EHF 1/7 1 3 1 2
Samsung UJ59 1/6 1/2 1/5 1/2 1
1.1.2.3.6 Colores:
LG UltraFine 40WT95UF Asus TUF Gaming VG27AQ3A MSI MAG401QR Asus VZ27EHF Samsung UJ59
LG UltraFine 40WT95UF 1 7 1 7 1
Asus TUF Gaming VG27AQ3A 1/7 1 1/7 1 1/7
MSI MAG401QR 1 7 1 7 1
Asus VZ27EHF 1/7 1 1/7 1 1/7
Samsung UJ59 1 7 1 7 1
1.1.2.3.7 Tamaño:
LG UltraFine 40WT95UF Asus TUF Gaming VG27AQ3A MSI MAG401QR Asus VZ27EHF Samsung UJ59
LG UltraFine 40WT95UF 1 7 1 7 5
Asus TUF Gaming VG27AQ3A 1/7 1 1/7 1 1/3
MSI MAG401QR 1 7 1 7 5
Asus VZ27EHF 1/7 1 1/7 1 1/3
Samsung UJ59 1/5 1/3 1/5 1/3 1
1.1.2.3.8 Frecuencia:
LG UltraFine 40WT95UF Asus TUF Gaming VG27AQ3A MSI MAG401QR Asus VZ27EHF Samsung UJ59
LG UltraFine 40WT95UF 1 1/5 1/3 5 7
Asus TUF Gaming VG27AQ3A 5 1 3 7 9
MSI MAG401QR 3 1/3 1 6 8
Asus VZ27EHF 1/5 1/7 1/6 1 3
Samsung UJ59 1/7 1/9 1/8 1/3 1

1.2 AHP con R

1.2.1 Introducción de las matrices en R

En primer lugar vamos a introducir las matrices de comparación por parejas para emplear las funciones de clase. Se ha utilizado además la función multicriterio.metodoAHP.chequeo.matrizcomparaciones para asegurar que las matrices son válidas.

## CRITERIOS

matriz_criterios_ahp <- multicriterio.crea.matrizvaloraciones_mej(
    c(1/7,1/5,3), numalternativas = 3, v.nombres.alternativas = c(
        "Coste", "Calidad de Imagen", "Experiencia de Usuario"))

## SUBCRITERIOS

#Coste
matriz_subcriterio_coste_ahp <- multicriterio.crea.matrizvaloraciones_mej(
    c(5), numalternativas = 2, v.nombres.alternativas = c("Precio", "Consumo"))

#Calidad de imagen
matriz_subcriterio_calidad_ahp <- multicriterio.crea.matrizvaloraciones_mej(
    c(2,7,5,5,3,1/3), numalternativas = 4, v.nombres.alternativas = c(
        "Resolución", "Densidad", "Brillo", "Colores"))

#Experiencia de usuario
matriz_subcriterio_experiencia_ahp <- multicriterio.crea.matrizvaloraciones_mej(
    c(3), numalternativas = 2, v.nombres.alternativas = c("Tamaño", "Frecuencia"))

## ALTERNATIVAS
 
#Precio
matriz_alternativas_precio_ahp <- multicriterio.crea.matrizvaloraciones_mej(
    c(1/7,1/2,1/9,1/5,5,1/4,3,1/7,1/4,5), numalternativas = 5, v.nombres.alternativas = datos$Modelo)

#Consumo
matriz_alternativas_consumo_ahp <- multicriterio.crea.matrizvaloraciones_mej(
    c(1/4,1/2,1/9,1/3,3,1/6,2,1/8,3,7), numalternativas = 5, v.nombres.alternativas = datos$Modelo)

#Resolución
matriz_alternativas_resolucion_ahp <- multicriterio.crea.matrizvaloraciones_mej(
    c(5,5,9,1,1,3,1/5,3,1/5,1/9), numalternativas = 5, v.nombres.alternativas = datos$Modelo)

#Densidad
matriz_alternativas_densidad_ahp <- multicriterio.crea.matrizvaloraciones_mej(
    c(3,5,7,1,3,5,1/3,3,1/5,1/7), numalternativas = 5, v.nombres.alternativas = datos$Modelo)

#Brillo
matriz_alternativas_brillo_ahp <- multicriterio.crea.matrizvaloraciones_mej(
    c(7,2,7,6,1/3,1,2,6,5,2), numalternativas = 5, v.nombres.alternativas = datos$Modelo)

#Colores
matriz_alternativas_colores_ahp <- multicriterio.crea.matrizvaloraciones_mej(
    c(7,1,7,1,1/7,1,1/7,7,1,1/7), numalternativas = 5, v.nombres.alternativas = datos$Modelo)

#Tamaño
matriz_alternativas_tamaño_ahp <- multicriterio.crea.matrizvaloraciones_mej(
    c(7,1,7,5,1/7,1,1/3,7,5,1/3), numalternativas = 5, v.nombres.alternativas = datos$Modelo)

# Frecuencia
matriz_alternativas_frecuencia_ahp <- multicriterio.crea.matrizvaloraciones_mej(
    c(1/5,1/3,5,7,3,7,9,6,8,3), numalternativas = 5, v.nombres.alternativas = datos$Modelo)
## Intento trabajar con listas para reducir el código

lista_matrices_parejas <- list(matriz_criterios_ahp,
                               matriz_subcriterio_coste_ahp,
                               matriz_subcriterio_calidad_ahp,
                               matriz_subcriterio_experiencia_ahp,
                               matriz_alternativas_precio_ahp,
                               matriz_alternativas_consumo_ahp,
                               matriz_alternativas_resolucion_ahp,
                               matriz_alternativas_densidad_ahp,
                               matriz_alternativas_brillo_ahp,
                               matriz_alternativas_colores_ahp,
                               matriz_alternativas_tamaño_ahp,
                               matriz_alternativas_frecuencia_ahp)

## Le ponemos nombres para facilitar su localización
nombres_matrices <- c("Criterios", "Coste", "Calidad", "Experiencia",
                                "Precio", "Consumo", "Resolución", "Densidad",
                                "Brillo", "Colores", "Tamaño", "Frecuencia")
names(lista_matrices_parejas) <- nombres_matrices

## Ahora a todas las matrices de esta lista le aplicamos la función de inconsistencia

lista_inconsistencias <- lapply(lista_matrices_parejas, multicriterio.metodoAHP.coef.inconsistencia)

## Ahora a todas las matrices de la lista de matrices por parejas le aplicamos la función para calcular pesos

lista_pesos <- lapply(lista_matrices_parejas, multicriterio.metodoAHP.variante2.mediageometrica)

1.2.2 Inconsistencia

Se ha realizado una tabla que recoge el análisis de inconsistencia de todas las matrices empleadas en el método AHP. Además se incluye una columna que recoge la validación de la matriz para su uso en el método AHP.

## Al usar el método con listas, la hemos calculado también para matrices 2x2 sin ser necesario. 
# Esta función, permite redondear RI de aquellos que queremos calcular y sustituye NaN por "-"
# para mostrarlo en la tabla.

convertir_vector_valores_listaNaN <- function (x) {
    if(is.nan(x$RI.coef.inconsistencia)){
        inter <- "-"
    } else {
        inter <- round(x$RI.coef.inconsistencia,4)
    }
    return(inter)
}
tabla_inconsistencia_ahp <- data.frame(
    Matriz = c(
        "Criterios",
        "Subcriterio Coste",
        "Subcriterio Calidad de Imagen",
        "Subcriterio Experiencia de Usuario",
        "Alternativa Precio",
        "Alternativa Consumo",
        "Alternativa Resolución",
        "Alternativa Densidad",
        "Alternativa Brillo",
        "Alternativa Colores",
        "Alternativa Tamaño",
        "Alternativa Frecuencia"
    ),
    `RI Coeficiente inconsistencia` = sapply(lista_inconsistencias, convertir_vector_valores_listaNaN),
    Estado = sapply(lista_inconsistencias, function(x) x$mensaje),
    `Matriz aceptable` = sapply(lista_matrices_parejas, multicriterio.metodoAHP.chequeo.matrizcomparaciones))

    crea_tabla_estilo(tabla_inconsistencia_ahp, nombresfila = FALSE)
Matriz RI.Coeficiente.inconsistencia Estado Matriz.aceptable
Criterios 0.0559 Consistencia aceptable TRUE
Subcriterio Coste Consistencia aceptable TRUE
Subcriterio Calidad de Imagen 0.0254 Consistencia aceptable TRUE
Subcriterio Experiencia de Usuario Consistencia aceptable TRUE
Alternativa Precio 0.0658 Consistencia aceptable TRUE
Alternativa Consumo 0.0869 Consistencia aceptable TRUE
Alternativa Resolución 0.0094 Consistencia aceptable TRUE
Alternativa Densidad 0.0304 Consistencia aceptable TRUE
Alternativa Brillo 0.0298 Consistencia aceptable TRUE
Alternativa Colores 0 Consistencia aceptable TRUE
Alternativa Tamaño 0.021 Consistencia aceptable TRUE
Alternativa Frecuencia 0.0859 Consistencia aceptable TRUE
# Preparación matriz criterios*subcriterios

c11 <- lista_pesos$Criterios$valoraciones.ahp[1] * lista_pesos$Coste$valoraciones.ahp[1]
c12 <- lista_pesos$Criterios$valoraciones.ahp[1] * lista_pesos$Coste$valoraciones.ahp[2]
c21 <- lista_pesos$Criterios$valoraciones.ahp[2] * lista_pesos$Calidad$valoraciones.ahp[1]
c22 <- lista_pesos$Criterios$valoraciones.ahp[2] * lista_pesos$Calidad$valoraciones.ahp[2]
c23 <- lista_pesos$Criterios$valoraciones.ahp[2] * lista_pesos$Calidad$valoraciones.ahp[3]
c24 <- lista_pesos$Criterios$valoraciones.ahp[2] * lista_pesos$Calidad$valoraciones.ahp[4]
c31 <- lista_pesos$Criterios$valoraciones.ahp[3] * lista_pesos$Experiencia$valoraciones.ahp[1]
c32 <- lista_pesos$Criterios$valoraciones.ahp[3] * lista_pesos$Experiencia$valoraciones.ahp[2]

criterios_subcriterios <- c(c11,c12,c21,c22,c23,c24,c31,c32)
names(criterios_subcriterios) <- nombres_matrices[5:12]

mat_pesos_alternativas <- matrix(c(
                            sapply(lista_pesos[5:12],function(x) x$valoraciones.ahp)
                            ),
                            ncol = 5, nrow = 8, byrow = TRUE)

ponderaciones_final <- criterios_subcriterios %*% mat_pesos_alternativas
colnames(ponderaciones_final) <- datos$Modelo

ponderaciones_final
     LG UltraFine 40WT95UF Asus TUF Gaming VG27AQ3A MSI MAG401QR Asus VZ27EHF
[1,]             0.3428178                0.1285062    0.1855899   0.07897614
     Samsung UJ59
[1,]    0.2641099

1.3 AHP con paquete

En primer lugar tenemos que crear el archivo ahp que almacena el modelo necesario para este paquete.

modelo_ahp <- ahp::Load("modelo_monitores.ahp")
modelo_ahp
                              levelName
1  Elegir el mejor monitor de PC       
2   ¦--Coste                           
3   ¦   ¦--Precio                      
4   ¦   ¦   ¦--LG-UltraFine-40WT95UF   
5   ¦   ¦   ¦--Asus-TUF-Gaming-VG27AQ3A
6   ¦   ¦   ¦--MSI-MAG401QR            
7   ¦   ¦   ¦--Asus-VZ27EHF            
8   ¦   ¦   °--Samsung-UJ59            
9   ¦   °--Consumo                     
10  ¦       ¦--LG-UltraFine-40WT95UF   
11  ¦       ¦--Asus-TUF-Gaming-VG27AQ3A
12  ¦       ¦--MSI-MAG401QR            
13  ¦       ¦--Asus-VZ27EHF            
14  ¦       °--Samsung-UJ59            
15  ¦--Calidad                         
16  ¦   ¦--Resolución                  
17  ¦   ¦   ¦--LG-UltraFine-40WT95UF   
18  ¦   ¦   ¦--Asus-TUF-Gaming-VG27AQ3A
19  ¦   ¦   ¦--MSI-MAG401QR            
20  ¦   ¦   ¦--Asus-VZ27EHF            
21  ¦   ¦   °--Samsung-UJ59            
22  ¦   ¦--Densidad                    
23  ¦   ¦   ¦--LG-UltraFine-40WT95UF   
24  ¦   ¦   ¦--Asus-TUF-Gaming-VG27AQ3A
25  ¦   ¦   ¦--MSI-MAG401QR            
26  ¦   ¦   ¦--Asus-VZ27EHF            
27  ¦   ¦   °--Samsung-UJ59            
28  ¦   ¦--Brillo                      
29  ¦   ¦   ¦--LG-UltraFine-40WT95UF   
30  ¦   ¦   ¦--Asus-TUF-Gaming-VG27AQ3A
31  ¦   ¦   ¦--MSI-MAG401QR            
32  ¦   ¦   ¦--Asus-VZ27EHF            
33  ¦   ¦   °--Samsung-UJ59            
34  ¦   °--Colores                     
35  ¦       ¦--LG-UltraFine-40WT95UF   
36  ¦       ¦--Asus-TUF-Gaming-VG27AQ3A
37  ¦       ¦--MSI-MAG401QR            
38  ¦       ¦--Asus-VZ27EHF            
39  ¦       °--Samsung-UJ59            
40  °--Experiencia                     
41      ¦--Tamaño                      
42      ¦   ¦--LG-UltraFine-40WT95UF   
43      ¦   ¦--Asus-TUF-Gaming-VG27AQ3A
44      ¦   ¦--MSI-MAG401QR            
45      ¦   ¦--Asus-VZ27EHF            
46      ¦   °--Samsung-UJ59            
47      °--Frecuencia                  
48          ¦--LG-UltraFine-40WT95UF   
49          ¦--Asus-TUF-Gaming-VG27AQ3A
50          ¦--MSI-MAG401QR            
51          ¦--Asus-VZ27EHF            
52          °--Samsung-UJ59            
#Paso 2. Calcular las prioridades
Calculate(modelo_ahp,pairwiseFun = )
print(modelo_ahp, priority = function(x) x$parent$priority["Total", x$name])
                              levelName   priority
1  Elegir el mejor monitor de PC                NA
2   ¦--Coste                            0.07192743
3   ¦   ¦--Precio                       0.83333333
4   ¦   ¦   ¦--LG-UltraFine-40WT95UF    0.03431168
5   ¦   ¦   ¦--Asus-TUF-Gaming-VG27AQ3A 0.24172104
6   ¦   ¦   ¦--MSI-MAG401QR             0.05287642
7   ¦   ¦   ¦--Asus-VZ27EHF             0.53807774
8   ¦   ¦   °--Samsung-UJ59             0.13301313
9   ¦   °--Consumo                      0.16666667
10  ¦       ¦--LG-UltraFine-40WT95UF    0.04222234
11  ¦       ¦--Asus-TUF-Gaming-VG27AQ3A 0.16516041
12  ¦       ¦--MSI-MAG401QR             0.10085747
13  ¦       ¦--Asus-VZ27EHF             0.61637062
14  ¦       °--Samsung-UJ59             0.07538916
15  ¦--Calidad                          0.64911800
16  ¦   ¦--Resolución                   0.52316601
17  ¦   ¦   ¦--LG-UltraFine-40WT95UF    0.39445497
18  ¦   ¦   ¦--Asus-TUF-Gaming-VG27AQ3A 0.08748681
19  ¦   ¦   ¦--MSI-MAG401QR             0.08748681
20  ¦   ¦   ¦--Asus-VZ27EHF             0.03611644
21  ¦   ¦   °--Samsung-UJ59             0.39445497
22  ¦   ¦--Densidad                     0.29762362
23  ¦   ¦   ¦--LG-UltraFine-40WT95UF    0.36209259
24  ¦   ¦   ¦--Asus-TUF-Gaming-VG27AQ3A 0.16068924
25  ¦   ¦   ¦--MSI-MAG401QR             0.07620127
26  ¦   ¦   ¦--Asus-VZ27EHF             0.03892431
27  ¦   ¦   °--Samsung-UJ59             0.36209259
28  ¦   ¦--Brillo                       0.05702733
29  ¦   ¦   ¦--LG-UltraFine-40WT95UF    0.49147039
30  ¦   ¦   ¦--Asus-TUF-Gaming-VG27AQ3A 0.08484712
31  ¦   ¦   ¦--MSI-MAG401QR             0.29495481
32  ¦   ¦   ¦--Asus-VZ27EHF             0.07527092
33  ¦   ¦   °--Samsung-UJ59             0.05345676
34  ¦   °--Colores                      0.12218304
35  ¦       ¦--LG-UltraFine-40WT95UF    0.30434783
36  ¦       ¦--Asus-TUF-Gaming-VG27AQ3A 0.04347826
37  ¦       ¦--MSI-MAG401QR             0.30434783
38  ¦       ¦--Asus-VZ27EHF             0.04347826
39  ¦       °--Samsung-UJ59             0.30434783
40  °--Experiencia                      0.27895457
41      ¦--Tamaño                       0.75000000
42      ¦   ¦--LG-UltraFine-40WT95UF    0.39665807
43      ¦   ¦--Asus-TUF-Gaming-VG27AQ3A 0.04845616
44      ¦   ¦--MSI-MAG401QR             0.39665807
45      ¦   ¦--Asus-VZ27EHF             0.04845616
46      ¦   °--Samsung-UJ59             0.10977153
47      °--Frecuencia                   0.25000000
48          ¦--LG-UltraFine-40WT95UF    0.15055981
49          ¦--Asus-TUF-Gaming-VG27AQ3A 0.49963246
50          ¦--MSI-MAG401QR             0.26726593
51          ¦--Asus-VZ27EHF             0.05330542
52          °--Samsung-UJ59             0.02923638
#Paso 3. Visualizar la jerarquía
Visualize(modelo_ahp)
#Paso 4. Analizar
Analyze(modelo_ahp,variable = "priority" ,sort="orig")
                                 Priority LG-UltraFine-40WT95UF
1  Elegir el mejor monitor de PC   100.0%                    NA
2   ¦--Coste                         7.2%                    NA
3   ¦   ¦--Precio                   83.3%                  3.4%
4   ¦   °--Consumo                  16.7%                  4.2%
5   ¦--Calidad                      64.9%                    NA
6   ¦   ¦--Resolución               52.3%                 39.4%
7   ¦   ¦--Densidad                 29.8%                 36.2%
8   ¦   ¦--Brillo                    5.7%                 49.1%
9   ¦   °--Colores                  12.2%                 30.4%
10  °--Experiencia                  27.9%                    NA
11      ¦--Tamaño                   75.0%                 39.7%
12      °--Frecuencia               25.0%                 15.1%
   Asus-TUF-Gaming-VG27AQ3A MSI-MAG401QR Asus-VZ27EHF Samsung-UJ59
1                        NA           NA           NA           NA
2                        NA           NA           NA           NA
3                     24.2%         5.3%        53.8%        13.3%
4                     16.5%        10.1%        61.6%         7.5%
5                        NA           NA           NA           NA
6                      8.7%         8.7%         3.6%        39.4%
7                     16.1%         7.6%         3.9%        36.2%
8                      8.5%        29.5%         7.5%         5.3%
9                      4.3%        30.4%         4.3%        30.4%
10                       NA           NA           NA           NA
11                     4.8%        39.7%         4.8%        11.0%
12                    50.0%        26.7%         5.3%         2.9%
   Inconsistency
1           6.2%
2           0.0%
3           6.6%
4           8.8%
5           2.6%
6           0.9%
7           3.1%
8           3.0%
9           0.0%
10          0.0%
11          2.1%
12          8.7%
#Paso 4b. alternativo
Analyze(modelo_ahp)
                                 Weight LG-UltraFine-40WT95UF Samsung-UJ59
1  Elegir el mejor monitor de PC 100.0%                 34.2%        26.4%
2   ¦--Calidad                    64.9%                 24.6%        23.0%
3   ¦   ¦--Resolución             34.0%                 13.4%        13.4%
4   ¦   ¦--Densidad               19.3%                  7.0%         7.0%
5   ¦   ¦--Colores                 7.9%                  2.4%         2.4%
6   ¦   °--Brillo                  3.7%                  1.8%         0.2%
7   ¦--Experiencia                27.9%                  9.3%         2.5%
8   ¦   ¦--Tamaño                 20.9%                  8.3%         2.3%
9   ¦   °--Frecuencia              7.0%                  1.0%         0.2%
10  °--Coste                       7.2%                  0.3%         0.9%
11      ¦--Precio                  6.0%                  0.2%         0.8%
12      °--Consumo                 1.2%                  0.1%         0.1%
   MSI-MAG401QR Asus-TUF-Gaming-VG27AQ3A Asus-VZ27EHF Inconsistency
1         18.5%                    12.9%         8.0%          6.2%
2          7.9%                     6.7%         2.6%          2.6%
3          3.0%                     3.0%         1.2%          0.9%
4          1.5%                     3.1%         0.8%          3.1%
5          2.4%                     0.3%         0.3%          0.0%
6          1.1%                     0.3%         0.3%          3.0%
7         10.2%                     4.5%         1.4%          0.0%
8          8.3%                     1.0%         1.0%          2.1%
9          1.9%                     3.5%         0.4%          8.7%
10         0.4%                     1.6%         4.0%          0.0%
11         0.3%                     1.4%         3.2%          6.6%
12         0.1%                     0.2%         0.7%          8.8%
#Paso 5. Analizar con Tabla Mejorada
aa = AnalyzeTable(modelo_ahp)
formattable::as.htmlwidget(aa)
#Paso 5b. alternativo
aa = AnalyzeTable(modelo_ahp,variable = "priority",sort = "orig")
formattable::as.htmlwidget(aa)
ahp::RunGUI()

Para los métodos siquientes se van a emplear los pesos que hemos calculado usando el método AHP, de forma que podamos comparar los distintos métodos y sus resultados. Los teníamos almacenados en el vector criterios_subcriterios.

criterios_subcriterios
    Precio    Consumo Resolución   Densidad     Brillo    Colores     Tamaño 
0.05993952 0.01198790 0.33961705 0.19430335 0.03667901 0.07851859 0.20921592 
Frecuencia 
0.06973864 

1.3.1 Matriz de decisión

Se establece la matriz de decisión, tenemos que hacer negativos los valores que se van a minimizar.

matriz_decisión <- multicriterio.crea.matrizdecision(
                    c(-505,-40,2160,139,450,1060,39.7,120,
                      -244,-35,1440,108,250,16.7,27,180,
                      -449,-39,1440,93,400,1070,40,155,
                      -108,-21,1080,81,250,16.7,27,100,
                      -290,-37,2160,139,270,1000,31.5,60
                    ), 
                    numalternativas = 5,
                    numcriterios = 8
)

matriz_decisión
     C1  C2   C3  C4  C5     C6   C7  C8
a1 -505 -40 2160 139 450 1060.0 39.7 120
a2 -244 -35 1440 108 250   16.7 27.0 180
a3 -449 -39 1440  93 400 1070.0 40.0 155
a4 -108 -21 1080  81 250   16.7 27.0 100
a5 -290 -37 2160 139 270 1000.0 31.5  60

1.3.2 Establecemos los parámetros para el método

1.3.2.1 Pesos

Como se ha mencionado anteriormente, vamos a emplear los pesos que hemos obtenido tras emplear el método AHP para los criterios y subcriterios

1.3.2.2 Test de concordancia

El test de concordancia requiere un valor alfa que al ser reducido permite que más alternativas dominen a otras. El valor de alfa inicial que vamos a tomar es 0.7.

1.3.2.3 Test de discordancia

Los valores para \(d_i\) pueden condicionar el resultado, en nuestro caso tenemos pocas alternativas, de características y rangos de precio muy variadas. Que lo hacen muy sensible a estos valores.

  • Brillo: Una diferencia mayor de 50 nits en el brillo será suficiente para no pasar el test de discordancia.
  • Colores: Se considera que diferencias menores a 100 (millones de colores) son insuficientes para no pasar el test de discordancia.
  • Tamaño de pantalla: Una diferencia mayor de 3” hará que no se supere el test de discordancia

A continuación se proponen otros posibles valores para ejemplos con mayor cantidad de alternativas o con modelos de una gama similar.

  • Precio: 150€
  • Consumo: 15W
  • Resolución: 720 px
  • Densidad de píxeles: 40 ppi
  • Frecuencia de refresco: 60 Hz

Además se considera que estas cantidades deberían ser ajustadas e introducidas en el método acorde a los pesos y las magnitudes. Por ejemplo, si se hubiera dado mayor importancia al precio en los pesos podríamos introducirlo como elemento para no superar el test de discordancia.

Algunas de las cantidades propuestas, como la resolución, serían adecuadas para este problema. La no influencia en el resultado final ha desincentivado su inclusión.

1.3.3 Primera iteración

iteración1_ELECTRE <- multicriterio.metodoELECTRE_I(matriz_decisión, 
                                                    pesos.criterios = criterios_subcriterios,
                                                    nivel.concordancia.minimo.alpha = 0.7,
                                                    no.se.compensan = c(Inf,Inf,Inf,Inf,50,100,3,Inf),
                                                    que.alternativas = TRUE
)

iteración1_ELECTRE$nucleo_aprox
a1 a3 
 1  3 
qgraph::qgraph(iteración1_ELECTRE$relacion.dominante)

test <- func_ELECTRE_Completo(iteración1_ELECTRE)

Vemos que para este valor de alfa, las mejores alternativas son a1 y a3. Y observando el grafo podríamos concluir que la siguiente mejor opción es a5.

Vamos a reducir el valor de alfa y nos vamos

iteración2_ELECTRE <- multicriterio.metodoELECTRE_I(matriz_decisión, 
                                                    pesos.criterios = criterios_subcriterios,
                                                    nivel.concordancia.minimo.alpha = 0.6,
                                                    no.se.compensan = c(Inf,Inf,Inf,Inf,50,100,3,Inf),
                                                    que.alternativas = c(1,3)
)

iteración2_ELECTRE$nucleo_aprox
a1 a3 
 1  2 
qgraph::qgraph(iteración2_ELECTRE$relacion.dominante, color = "#F8A29E", edge.color = "#005682" , edge.width = 1)

posiciones <- qgraph::qgraph(iteración1_ELECTRE$relacion.dominante, layout = "spring")

animacion <- qgraph::qgraph.animate(iteración1_ELECTRE$relacion.dominante, color = "#F8A29E", edge.color = "#005682" , edge.width = 1, constraint = Inf,
growth = "order", sleep = 0, smooth = TRUE, plotGraphs = FALSE, progress = FALSE, initLayout = posiciones$layout)

img_list <- lapply(animacion, function(g) {
  tmpfile <- tempfile(fileext = ".png")
  png(tmpfile, width = 600, height = 600)
  plot(g)
  dev.off()
  magick::image_read(tmpfile)
})

gif <- magick::image_animate(magick::image_join(img_list), fps = 0.5)
gif

magick::image_write(gif, "animacion_electre.gif")

Vemos que para este valor de alfa, las mejores alternativas son a1 y a3. Y observando el grafo podríamos concluir que la siguiente mejor opción es a5.

Vamos a reducir el valor de alfa y las

1.4 Tab

1.4.1 Funciones de preferencia

Para cada criterio vamos a elegir una función de preferencia según la naturaleza de cada uno, tratando además que proporcionen mayor satisfacción a los requisitos del arquitecto. Recordemos los criterios:

  • Precio: El precio no está entre los requisitos más importantes, pero queremos que tenga algo de indicencia en la decisión final, querríamos que para cantidades con diferencias pequeñas no exista preferencia alguna. Por ello vamos a tomar un valor de Q= 50€

  • Consumo: El coste anual que supone una diferencia de 10W trabajando es de 2.4€; Cálculo: 10W = 0.01 kW, 6 horas al día todos los días, 0.01 kW x 6 x 365 = 21.90 kWh anuales. Con el precio medio actual 0.1090 €/kWh: 21.90 kWh x 0.1090 €/kWh = 2.3871€. Esto motiva que sigamos optemos por el Cuasi-Criterio. Con no preferencia en todas las diferencias menores que Q = 10W.

  • Resolución: Aquí queremos que haya dominancia absoluta en aquellos valores que superen a otros por 720 px, de esta forma establecemos niveles bien diferenciados según la resolución. Preferencia lineal

  • Densidad: Para la densidad de píxeles vamos a emplear el criterio usual, queremos que cualquier diferencia positiva resulte en preferencia absoluta. Si tuviéramos monitores con densidad de píxeles por encima de 150 elegiríamos un criterio que nos permitiera diferenciar que a partir de esa cantidad apenas existe diferencia.

  • Brillo: Para el brillo vamos a optar por dar preferencia a monitores con más de 100 nits de diferencia. Preferencia lineal.

  • Colores: En el caso de los colores vamos a tratar de diferenciar aquellos con 16.7 millones de colores de aquellos que tienen +1000 millones de colores. Así cuando la diferencia sea menor de 100 (M) diremos que no hay preferencia. Cuasi-criterio.

  • Tamaño: En cuanto al tamaño, queremos que monitores de tamaños muy similares no tengan dominancia entre si y que cualquier salto de tamaño medio nos proporcione dominancia absoluta. Para ello P = 4” y Q = 2”. Función elegida lineal con área de indiferencia.

  • Frecuencia: La frecuencia de refresco sigue una escala particular, normalmente saltos de 30 Hz se hacen notar bastante hasta cierta cantidad de Hz que los saltos deben ser mayores para que se note. Como para el arquitecto es un factor secundario, vamos a tomar que diferencias menores a 20 Hz no supondrán preferencia de una alternativa sobre otra y que saltos de 59 Hz si harán que escojamos una alternativa con preferencia absoluta. Para los valores intermedios queremos un reparto suavizado, vamos a tomar S = 60 Hz

tabla_preferencia <- matrix(c(2,50,0,0, 
                              2,10,0,0, 
                              3,0,720,0,
                              1,0,0,0,
                              3,0,100,0,
                              2,100,0,0,
                              5,2,4,0,
                              6,60,20,60),
                              ncol = 4, 
                              byrow = TRUE)

1.5 PROMETHEE I

resultado_Promethee_I <- multicriterio.metodo.promethee_i(matriz_decisión,
                                                        criterios_subcriterios,
                                                        tabla_preferencia)

resultado_Promethee_I$tabla.indices
           a1         a2         a3        a4         a5
a1 0.00000000 0.85833393 0.55225991 0.8621026 0.27333496
a2 0.08737954 0.00000000 0.26004127 0.4051801 0.06030054
a3 0.07085030 0.32441353 0.00000000 0.7124489 0.29572238
a4 0.07192743 0.07192743 0.07192743 0.0000000 0.08582373
a5 0.05993952 0.82899072 0.59385993 0.8289907 0.00000000
resultado_Promethee_I$tablarelacionsupera
    a1  a2  a3  a4  a5
a1 0.5 1.0 1.0 1.0 1.0
a2 0.0 0.5 0.0 1.0 0.0
a3 0.0 1.0 0.5 1.0 0.0
a4 0.0 0.0 0.0 0.5 0.0
a5 0.0 1.0 1.0 1.0 0.5
qgraph::qgraph(resultado_Promethee_I$tablarelacionsupera, color = "#F8A29E", edge.color = "#005682" , edge.width = 0.5)

1.5.1 Medias

resultado_Promethee_I_medias <- multicriterio.metodo.promethee_i_med(matriz_decisión, criterios_subcriterios, tabla_preferencia)

qgraph::qgraph(resultado_Promethee_I_medias$tablarelacionsupera)

1.6 PROMETHEE II

resultado_Promethee_II <- multicriterio.metodo.promethee_ii(matriz_decisión, criterios_subcriterios, tabla_preferencia)

resultado_Promethee_II$vflujos.netos
         a1          a2          a3          a4          a5 
 2.25593464 -1.27076414 -0.07465348 -2.50711630  1.59659928 
qgraph::qgraph(resultado_Promethee_II$tablarelacionsupera)

resultado_Promethee_II_Win <- multicriterio.metodo.promethee_windows(matriz_decisión, tabla_preferencia, criterios_subcriterios, c(rep("min",2),rep("max",6)))
    
source("teoriadecision_funciones_multicriterio_utiles.R")
test <- multicriterio.metodo.promethee_windows_kableExtra_html(resultado_Promethee_II_Win)
test$tabEscenario
Criterio1 Criterio2 Criterio3 Criterio4 Criterio5 Criterio6 Criterio7 Criterio8
Preferencias
Min/Max min min max max max max max max
Pesos 0.0599395249018804 0.0119879049803761 0.339617051476852 0.194303352071175 0.0366790139892087 0.0785185870940899 0.209215924114814 0.0697386413716046
Funciones Preferencias U-shape (2) U-shape (2) V-shape (3) Usual (1) V-shape (3) U-shape (2) Linear (5) Gaussian (6)
Q: Indiferencia 50 10 0 0 0 100 2 60
P: Preferencia 0 0 720 0 100 0 4 20
S: Gausiano 0 0 0 0 0 0 0 60
Estadísticas
Minimo 108 21 1080 81 250 16.7 27 60
Maximo 505 40 2160 139 450 1070 40 180
Media 319.2 34.4 1656 112 324 632.68 33.04 123
Desviacion Tipica 143.17 6.92 432 23.65 84.29 503.52 5.8 41.9
Evaluaciones
a1 505 40 2160 139 450 1060 39.7 120
a2 244 35 1440 108 250 16.7 27 180
a3 449 39 1440 93 400 1070 40 155
a4 108 21 1080 81 250 16.7 27 100
a5 290 37 2160 139 270 1000 31.5 60
test$tabAcciones
Rango Phi Phi.mas Phi.menos
a1 1 0.5640 0.6365 0.0725
a5 2 0.3991 0.5779 0.1788
a3 3 -0.0187 0.3509 0.3695
a2 4 -0.3177 0.2032 0.5209
a4 5 -0.6268 0.0754 0.7022